package com.mar.tech.unify.factory;

import io.vertx.core.Context;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.PubSecKeyOptions;
import io.vertx.ext.auth.jwt.JWTAuth;
import io.vertx.ext.auth.jwt.JWTAuthOptions;
import io.vertx.ext.jwt.JWTOptions;
import io.vertx.mysqlclient.MySQLConnectOptions;
import io.vertx.mysqlclient.MySQLPool;
import io.vertx.sqlclient.PoolOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Description: Vertx 工厂.<br>
 *
 * @author jm
 *     Created By 2018/11/24 下午2:58
 */
public class UnifyFactory {
  private final static Logger logger = LoggerFactory.getLogger(UnifyFactory.class);
  private static Vertx vertx;
  private static JsonObject config;
  private static JWTAuth jwtAuth;
  private static MySQLPool client;

  /**
   * 创建.
   *
   * @param vertxContext 上下文
   */
  public static void init(Context vertxContext, JsonObject config) {
    UnifyFactory.vertx = vertxContext.owner();
    UnifyFactory.config = config;
    enableJwt();
    enableMysql();
  }

  private static void enableJwt() {
    JWTAuthOptions options = new JWTAuthOptions();
    PubSecKeyOptions pubSecKeyOptions = new PubSecKeyOptions();
    pubSecKeyOptions.setAlgorithm("HS256");
    pubSecKeyOptions.setPublicKey("MCwwDQYJKoZIhvcNAQEBBQADGwAwGAIRANYOs5W08cnsV3Z73BSauNsCAwEAAQ==");
    pubSecKeyOptions.setSymmetric(true);
    options.addPubSecKey(pubSecKeyOptions);
    JWTOptions jwtOptions = new JWTOptions();
    jwtOptions.setAlgorithm("HS256");
    options.setJWTOptions(jwtOptions);
    jwtAuth = JWTAuth.create(vertx, options);
  }

  private static void enableMysql() {
    JsonObject database = UnifyFactory.config().getJsonObject("database", new JsonObject());
    MySQLConnectOptions connectOptions = new MySQLConnectOptions()
      .setPort(database.getInteger("port", 3306))
      .setHost(database.getString("host", "127.0.0.1"))
      .setDatabase(database.getString("database", "demo"))
      .setUser(database.getString("username", "root"))
      .setPassword(database.getString("password", "123456"))
      .setCachePreparedStatements(true)
      .setCharset(database.getString("charset", "utf8mb4"));
    PoolOptions poolOptions = new PoolOptions()
      .setMaxSize(database.getInteger("maxPoolSize", 5))
      .setMaxWaitQueueSize(database.getInteger("maxWaitQueueSize", 1024));
    client = MySQLPool.pool(vertx, connectOptions, poolOptions);
    client.query("select 1").execute(res -> {
      if (res.failed()) {
        logger.error("[Vert.x] Mysql Pool Creation Failure", res.cause());
        throw new RuntimeException(res.cause());
      }
      logger.info("[Vert.x] Mysql Pool {}/{} Connected.",
        database.getString("host", "127.0.0.1"),
        database.getString("database", "demo"));
    });
  }

  public static JsonObject config() {
    return config;
  }

  public static Vertx vertx() {
    return vertx;
  }

  public static MySQLPool mysql() {
    return client;
  }

  public static JWTAuth jwt() {
    return jwtAuth;
  }

  public static JsonObject getQuery() {
    return config.getJsonObject("query", new JsonObject());
  }
}
